[アップデート]CloudFormationでネストされたスタックの変更セットがサポートされるようになりました
いつものアップデート職人の執筆ではありませんが、ご容赦ください。
はじめに
仕事終わりにTwitterを眺めていたらCloudFormationのNested Stacksの変更セットがサポートしたというツイートを見つけました。(しかも13時間前だった。。)
AWS CloudFormation change sets now support nested stacks
Nested Stacksのこれまでとこれから
ネットワークやAWSサービス管理しやすい単位でテンプレートを管理し、ルートスタックからType: AWS::CloudFormation::Stack
で子スタックとしてテンプレートを呼び出していました。新規スタックの作成は何ら問題ないのですが、作成されたAWSリソースに変更を加える場合です。以前の記事でも書いた通り、子スタックのどのAWSリソースが変更されるか確認できませんでした。回避策として子スタックに対して変更セットだけ実施する方法も以前の記事で書いていたのですが、更新する子スタックが多数ある場合は現実的ではありません。
子スタックに対する変更セットが望む声が届いたのか、Nested Stacksの変更セットがサポートされたことで、子スタックで変更されるリソースを確認することができるようになります。
やってみる
今回試したのは、以下の構成です。
子スタック(ネットワーク関連、セキュリティグループ)とルートスタックのテンプレートです。
test-stack.yml
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
SystemName:
Type: String
MinLength: 1
MaxLength: 5
Default: nkhr
EnvironmentName:
Description: environment name
Type: String
AllowedValues:
- dev
- stg
- prd
Default: stg
DeletionProtection:
Type: String
AllowedValues:
- true
- false
Default: false
Resources:
VPC:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: "https://cf-templete-xxxxxx.s3-ap-northeast-1.amazonaws.com/stg/vpc.yml"
Parameters:
SystemName: !Sub ${SystemName}
EnvironmentName: !Sub ${EnvironmentName}
SG:
Type: AWS::CloudFormation::Stack
DependsOn: VPC
Properties:
TemplateURL: "https://cf-templete-xxxxxx.s3-ap-northeast-1.amazonaws.com/stg/sg.yml"
Parameters:
SystemName: !Sub ${SystemName}
EnvironmentName: !Sub ${EnvironmentName}
vpc.yml
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
SystemName:
Type: String
MinLength: 1
MaxLength: 5
Default: nkhr
EnvironmentName:
Description: environment name
Type: String
AllowedValues:
- dev
- stg
- prd
Default: stg
DeletionProtection:
Type: String
AllowedValues:
- true
- false
Default: false
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.11.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
InstanceTenancy: default
Tags:
-
Key: Name
Value: !Sub ${SystemName}-${EnvironmentName}-vpc
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
-
Key: Name
Value: !Sub ${SystemName}-${EnvironmentName}-igw
DHCPOptions:
Type: AWS::EC2::DHCPOptions
Properties:
DomainName: ap-northeast-1.compute.internal
DomainNameServers:
- AmazonProvidedDNS
Tags:
-
Key: Name
Value: !Sub ${SystemName}-${EnvironmentName}-dopt
DHCPOptionsAssociation:
Type: AWS::EC2::VPCDHCPOptionsAssociation
Properties:
VpcId: !Ref VPC
DhcpOptionsId: !Ref DHCPOptions
RouteTable1:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
-
Key: Name
Value: !Sub ${SystemName}-${EnvironmentName}-front-rtb
Route:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref RouteTable1
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
AttachInternetGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref VPC
NetworkAcl1:
Type: AWS::EC2::NetworkAcl
Properties:
VpcId: !Ref VPC
Tags:
-
Key: Name
Value: !Sub ${SystemName}-${EnvironmentName}-nacl
NetworkAclEntry1:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref NetworkAcl1
RuleNumber: 100
Protocol: -1
RuleAction: allow
Egress: true
CidrBlock: 0.0.0.0/0
Icmp:
Code: -1
Type: -1
PortRange:
From: -1
To: -1
NetworkAclEntry2:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref NetworkAcl1
RuleNumber: 100
Protocol: -1
RuleAction: allow
Egress: false
CidrBlock: 0.0.0.0/0
Icmp:
Code: -1
Type: -1
PortRange:
From: -1
To: -1
NetworkAclAssociation1:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref Subnet1
NetworkAclId: !Ref NetworkAcl1
Subnet1:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: ap-northeast-1a
CidrBlock: 10.11.0.0/24
VpcId: !Ref VPC
MapPublicIpOnLaunch: false
Tags:
-
Key: Name
Value: !Sub ${SystemName}-${EnvironmentName}-front-a-subnet
Subnet1RouteTableAssciation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref Subnet1
RouteTableId: !Ref RouteTable1
Outputs:
VPC:
Value: !Ref VPC
Export:
Name: !Sub ${SystemName}-${EnvironmentName}-vpc
Subnet1:
Value: !Ref Subnet1
Export:
Name: !Sub ${SystemName}-${EnvironmentName}-subnet1
sg.yml
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
SystemName:
Type: String
MinLength: 1
MaxLength: 5
Default: nkhr
EnvironmentName:
Description: environment name
Type: String
AllowedValues:
- dev
- stg
- prd
Default: stg
DeletionProtection:
Type: String
AllowedValues:
- true
- false
Default: false
Resources:
ALBSG:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: {"Fn::ImportValue": !Sub "${SystemName}-${EnvironmentName}-vpc"}
GroupDescription: ALB SG
SecurityGroupIngress:
-
IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
-
IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Tags:
-
Key: Name
Value: !Sub ${SystemName}-${EnvironmentName}-alb-sg
EC2SG:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: {"Fn::ImportValue": !Sub "${SystemName}-${EnvironmentName}-vpc"}
GroupDescription: WEB SG
SecurityGroupIngress:
-
IpProtocol: tcp
FromPort: 80
ToPort: 80
SourceSecurityGroupId: !Ref ALBSG
-
IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 106.xxx.xxx.xxx/32
Tags:
-
Key: Name
Value: !Sub ${SystemName}-${EnvironmentName}-web-sg
EC2SGIngressRule1:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !Ref EC2SG
IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 105.xxx.xxx.xxx/32
Outputs:
ALBSG:
Value: !Ref ALBSG
Export:
Name: !Sub ${SystemName}-${EnvironmentName}-alb-sg
EC2SG:
Value: !Ref EC2SG
Export:
Name: !Sub ${SystemName}-${EnvironmentName}-ec2-sg
ルートスタックのテンプレートを選択してスタックを作成後、子スタックの一部を変更してS3に格納し、ルートスタックから「既存スタックの変更セットの作成」を実行してみます。
ルートスタックに変更はないので「現在のテンプレートの使用」を選択します。
「ステップ 3 スタックオプションの設定の変更セット」にネストされたスタックの変更セット項目が追加されているので有効(デフォルト)にして変更セットを作成します。
変更セットが完了すると変更タブに子スタックの変更セットが表示できるようになっています。それぞれの子スタックの変更セットを見てみると対象の論理IDが確認することができます。
変更セット確認後、親スタックを更新します。変更セットの履歴にも上記と同じ内容が確認できます。
さいごに
今回のアップデートでコードによるインフラの運用管理が更に安心して実現しやすくなったと思います。なお、CloudFormationが利用できるすべてのAWSリージョンで追加料金なしで利用できます。既存のNeted Stacksにも適用されるのでCloudFormationの活用が広まるきっかけになるアップデートだと感じました。